<?php

/**
 * This is the model class for table "whm_account".
 *
 * The followings are the available columns in table 'whm_account':
 * @property integer $id_account
 * @property string $domain
 * @property string $username
 * @property string $ipaddress
 * @property integer $id_group
 * @property integer $id_host
 * @property string $accesshash
 * @property string $secure
 * @property string $pass
 * @property string $pass_secure
 * @property string $sshkey_pass
 * @property string $sshkey_pass_secure
 * @property string $sshkey
 * @property string $sshkey_secure
 * @property string $last_cp_update
 */
class WhmAccount extends CActiveRecord
{
	const TYPE_RESELLER = 'Reseller';
	const TYPE_ROOT = 'Root';
	
	public $EnAccessHash = true;
	public $EnPass = true;
	
	/**
	 * Returns the static model of the specified AR class.
	 * @param string $className active record class name.
	 * @return WhmAccount the static model class
	 */
	public static function model($className=__CLASS__)
	{
		return parent::model($className);
	}

	/**
	 * @return string the associated database table name
	 */
	public function tableName()
	{
		return 'whm_account';
	}

	/**
	 * @return array validation rules for model attributes.
	 */
	public function rules()
	{
		// NOTE: you should only define rules for those attributes that
		// will receive user inputs.
		return array(
			array('username, domain, ipaddress, id_group, id_host, accesshash', 'required'),
			array('id_group, id_host', 'numerical', 'integerOnly'=>true),
			array('domain', 'length', 'max'=>500),
			array('username, ipaddress, accesshash, pass, secure, pass_secure, last_cp_update', 'safe'),
			// The following rule is used by search().
			// Please remove those attributes that should not be searched.
			array('id_account, domain, username, ipaddress, id_group, id_host, accesshash, pass, secure, pass_secure, last_cp_update', 'safe', 'on'=>'search'),
		);
	}

	/**
	 * @return array relational rules.
	 */
	public function relations()
	{
		// NOTE: you may need to adjust the relation name and the related
		// class name for the relations automatically generated below.
		return array(
			'Group' => array(self::BELONGS_TO, 'Group', 'id_group'),
			'Host' => array(self::BELONGS_TO, 'Host', 'id_host'),
			
			'CpanelAccounts' => array(self::HAS_MANY, 'CpanelAccounts', array('id_account' => 'id_account')),
			'AccountFunctions' => array(self::HAS_ONE, 'WhmAccountFunctions', array('id_account' => 'id_account')),
			
			'SshSetup' => array(self::HAS_ONE, 'SshSetup', array('id_account' => 'id_account'))
		);
	}

	/**
	 * @return array customized attribute labels (name=>label)
	 */
	public function attributeLabels()
	{
		return array(
			'id_account' => t('info', 'Id Account'),
			'domain' => t('info', 'Domain'),
			'username' => t('info', 'Username'),
			'ipaddress' => t('info', 'IP'),
			'id_group' => t('info', 'Id Group'),
			'id_host' => t('info', 'Id Host'),
			'accesshash' => t('info', 'WHM Access Hash Key'),
			'secure' => t('info', 'Secure'),
			'pass_secure' => t('info', 'Password Secure'),
			'pass' => t('info', 'Password (optional)'),
			'last_cp_update' => t('info', 'Last Cp Update'),
		);
	}

	/**
	 * Retrieves a list of models based on the current search/filter conditions.
	 * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
	 */
	public function search($filterAccess = true)
	{
		// Warning: Please modify the following code to remove attributes that
		// should not be searched.

		$criteria=new CDbCriteria;

		$criteria->compare('id_account',$this->id_account);
		$criteria->compare('domain',$this->domain,true);
		$criteria->compare('username',$this->username,true);
		$criteria->compare('ipaddress',$this->ipaddress,true);
		$criteria->compare('id_group',$this->id_group);
		$criteria->compare('id_host',$this->id_host);
		$criteria->compare('accesshash',$this->accesshash,true);
		$criteria->compare('secure',$this->secure,true);
		$criteria->compare('pass_secure', $this->pass_secure, true);
		$criteria->compare('pass', $this->pass, true);
		$criteria->compare('last_cp_update',$this->last_cp_update,true);
		
		if($filterAccess){
			$criteria->addInCondition('id_account', User::model()->getFinalAccessdAccountIds());
		}
		
		$id_group = app()->request->getParam('id_group', null);
		if($id_group){
			$criteria->addCondition("t.id_group={$id_group}");
		}
		
		$id_host = app()->request->getParam('id_host', null);
		if($id_host){
			$criteria->addCondition("t.id_host={$id_host}");
		}

		$criteria->with = array('Group', 'Host');
		
		return new CActiveDataProvider($this, array(
			'criteria'=>$criteria,
			'sort' => array(
				'defaultOrder'=>'username ASC',
				'attributes' => array(
					'username_sort' => array(
						'asc' => 't.username ',
						'desc' => 't.username DESC',
					),
					'domain_sort' => array(
						'asc' => 't.domain',
						'desc' => 't.domain DESC',
					),
					'group_sort' => array(
						'asc'=>'Group.name',
						'desc'=>'Group.name DESC',
					),
					'host_sort' => array(
						'asc' => 'Host.name',
						'desc' => 'Host.name DESC',
					),
				)
			),
			'pagination' => array(
				'pageSize'=> app()->user->getData()->getIndividualConfig()->getPagination()
			)
		));
	}
	
	public function beforeSave() {
//		if ($this->isNewRecord){
			$this->accessHashEncode();
			$this->passEncode();
//		}
		return true;
	}
	
	public function afterSave()
	{
//		$this->fetchSshKey();
		
		return parent::afterSave();
	}
	
	public function afterDelete()
	{
//		CpanelAccounts::model()->deleteAllByAttributes(array('id_account' => $this->id_account));
//		WhmAccountFunctions::model()->deleteAllByAttributes(array('id_account' => $this->id_account));
//		UserRolePermAccount::model()->deleteAllByAttributes(array('id_account' => $this->id_account));

		$this->sanitizeDb();
		return parent::afterDelete();
	}
	
	
	
	public function accessHashEncode()
	{
		if(!empty($this->accesshash)){
			if($this->EnAccessHash){
				$crypt = new Crypt();
				$this->accesshash = $crypt->encrypt($this->accesshash);
				$this->secure = $crypt->getKey();
			}
		}
	}
	
	public function accessHashDecode()
	{
		$crypt = new Crypt();
		return $crypt->decrypt($this->accesshash, $this->secure);
	}
	
	public function getPlainAccessHash()
	{
		if(empty($this->secure)){
			return $this->accesshash;
		}else{
			return $this->accessHashDecode();
		}
	}
	
	public function passEncode()
	{
		if(!empty($this->pass)){
			if($this->EnPass){
				$crypt = new Crypt();
				$this->pass = $crypt->encrypt($this->pass);
				$this->pass_secure = $crypt->getKey();
			}
		}
	}
	
	public function passDecode()
	{
		$crypt = new Crypt();
		return $crypt->decrypt($this->pass, $this->pass_secure);
	}
	
	public function getPlainPass()
	{
		if(empty($this->pass_secure)){
			return $this->pass;
		}else{
			return $this->passDecode();
		}
	}
	
	public function fetchSshKey()
	{
		if($this->username == WhmApi::ROOT_USERNAME){
			if(empty($this->sshkey)){
				$whmApi = new WhmApi($this);
				if($whmApi->AccountAuthByHash()){
					$name = '__whatever___' . $this->id_account;
					$pass = substr(str_shuffle('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789*()_!~<>.'), 0, rand(6, 12));
					$sshkey = $whmApi->GenSshkey($name, $pass);	die();
				}
			}
		}
	}
	
	public function sanitizeDb()
	{
		$allAccounts = $this->findAll();
		$id_accounts = CHtml::listData($allAccounts, 'id_account', 'id_account');
		
		$criteria = new CDbCriteria();
		$criteria->addNotInCondition('id_account', $id_accounts);
		CpanelAccounts::model()->deleteAll($criteria);
		WhmAccountFunctions::model()->deleteAll($criteria);
		UserRolePermAccount::model()->deleteAll($criteria);
		
		return true;
	}
	
	public function reLoadCpanelAccounts($save = true, $now = null)
	{
		$now = $now? $now : time();
		$whmApi = new WhmApi($this);
		if($whmApi->AccountAuthByHash()){
			$cpanelAccounts = $whmApi->getAccountData();
			if($cpanelAccounts !== false){
				if($save){
					foreach($this->CpanelAccounts as $ca){
						$ca->delete();
					}
					
					foreach($cpanelAccounts as $cpanelAccount){
						$cpanelAccountModel = new CpanelAccounts();
						$cpanelAccountModel->id_account = $this->getPrimaryKey();
						$cpanelAccountModel->domain = $cpanelAccount->domain;
						$cpanelAccountModel->IP = $cpanelAccount->ip;
						$cpanelAccountModel->username = $cpanelAccount->user;
						$cpanelAccountModel->theme = $cpanelAccount->theme;
						$cpanelAccountModel->owner = $cpanelAccount->owner;
						$cpanelAccountModel->setup_date = $cpanelAccount->startdate;
						$cpanelAccountModel->quota = $cpanelAccount->disklimit;
						$cpanelAccountModel->disk_used = $cpanelAccount->diskused;
						if(!$cpanelAccountModel->save()){
							$this->addErrors($cpanelAccountModel->getErrors());
							return false;
						}
					}
					
					$oldEnAccessHash = $this->EnAccessHash;
					$oldEnPass = $this->EnPass;
					$this->EnAccessHash = false;
					$this->EnPass = false;
					
					$this->last_cp_update = $now;
					$this->save();
					
					$this->EnAccessHash = $oldEnAccessHash;
					$this->EnPass = $oldEnPass;
				}
			}else{
				//$this->addErrors($whmApi->getErrors());	//has added in WhmApi by $this point
				return false;
			}
		}else{
			//$this->addErrors($whmApi->getErrors());	//has added in WhmApi by $this point
			return false;
		}

		return true;
	}
	
	public function reLoadFunctions($save = true, $now = null)
	{
		$now = $now? $now : time();
		$whmApi = new WhmApi($this);
		if($whmApi->AccountAuthByHash()){
			$accountFunctions = $whmApi->AppList();
			if($accountFunctions !== false){
				if($save){
					if(!empty($this->AccountFunctions)){
						$this->AccountFunctions->delete();
					}
					$accountFunctionsModel = new WhmAccountFunctions();
					$funcsSet = array_combine($accountFunctions, array_pad(array(), count($accountFunctions), 1));
					$accountFunctionsModel->id_account = $this->getPrimaryKey();
					$accountFunctionsModel->attributes = $funcsSet;
					if(!$accountFunctionsModel->save()){
						$this->addErrors($accountFunctionsModel->getErrors());
						return false;
					}	

					$oldEnAccessHash = $this->EnAccessHash;
					$oldEnPass = $this->EnPass;
					$this->EnAccessHash = false;
					$this->EnPass = false;
					
					$this->last_cp_update = $now;
					$this->save();
					
					$this->EnAccessHash = $oldEnAccessHash;
					$this->EnPass = $oldEnPass;
				}
			}else{
				//$this->addErrors($whmApi->getErrors());	//has added in WhmApi by $this point
				return false;
			}
		}else{
			//$this->addErrors($whmApi->getErrors());	//has added in WhmApi by $this point
			return false;
		}

		return true;
	}
	
	public function accountChiefInfoChanged()
	{
		$dbData = WhmAccount::model()->findByPk($this->getPrimaryKey());
		if($this->domain != $dbData->domain){
			return true;
		}else if($this->ipaddress != $dbData->ipaddress){
			return true;
		}else if($this->username != $dbData->username){
			return true;
		}else if($this->accesshash != $dbData->accesshash){
			return true;	
		}
		
		return false;
	}
	
	public function renderListActionButtons()
	{
		return '
			<div class="btn-group">
				<button class="btn btn-info dropdown-toggle actions" data-toggle="dropdown">
					'. t('buttons', 'Actions') .'
					<span class="caret"></span>
				</button>
				<ul class="dropdown-menu">
					<li class="account_cpanel_accounts"><a href="javascript:void(0);"><i class="radmin-icon radmin-clipboard"></i> '.t('buttons', 'List cPanel Accounts').'</a></li>
					<li class="account_whm_login ' . (empty($this->pass)? 'hide' : '') . '"><a href="'. url('whm/account/login', array('id_account' => $this->id_account)) .'" target="_blank"><i class="radmin-icon radmin-enter"></i> '.t('buttons', 'WHM Login').'</a></li>
					<li class="account_pull_cpanel"><a href="javascript:void(0);"><i class="radmin-icon radmin-loading"></i> '.t('buttons', 'Pull Fresh cPanel Data').'</a></li>
					<li class="account_setup_hostlogin"><a href="javascript:void(0);"><i class="radmin-icon radmin-enter"></i> '.t('buttons', 'Setup Host Login').'</a></li>
					<li class="account_edit"><a href="javascript:void(0);"><i class="radmin-icon radmin-pencil"></i> '.t('buttons', 'Edit').'</a></li>
					<li class="account_delete"><a href="javascript:void(0);"><i class="radmin-icon radmin-remove"></i> '.t('buttons', 'Delete').'</a></li>
				</ul>
				
				<div class="delete_confirm_btn hide">
					<a class="btn btn-small delete_confirm"><i class="icon-ok"></i>'.t('buttons', 'Confirm Delete').'</a>
					<a class="btn btn-small delete_cancel"><i class="icon-remove"></i>'.t('buttons', 'Cancel').'</a>
				</div>
			</div>
		';
	}
	
	public function __get($key)
	{
		$action = 'get' . str_replace(' ', '', ucwords(str_replace('_', ' ', $key)));
		if(method_exists($this, $action)){
			return $this->$action();
		}
		
		return parent::__get($key);
	}
	
	public function getDomainWithIndividualLink()
	{
		return CHtml::link($this->domain, url('whm/account/individual', array('id_account' => $this->id_account)));
	}

	public function getLoadAvgHistory($limit = 6, $cronName = 'onehour', $dataProvideType = 'google_line', $timeFormat = 'H:i')
	{
		$criteria = new CDbCriteria();
		$criteria->addCondition("id_account={$this->id_account}");
		$criteria->addCondition("cron_name='{$cronName}'");
		$criteria->order = 'time_date DESC';
		$criteria->limit = $limit;
		
		$loadHistory = CronLoadData::model()->findAll($criteria);
		$loadHistory = array_reverse($loadHistory);
		$data = array();
		$time = array();
		if($dataProvideType == 'google_line'){
			foreach($loadHistory as $history){
				$timeFormated = date($timeFormat, strtotime($history->time_date));
				$time[] = $timeFormated;
				$data['one'][$timeFormated] = $history->whm_server_loadavg_one * 100;
				$data['five'][$timeFormated] = $history->whm_server_loadavg_five * 100;
				$data['fifteen'][$timeFormated] = $history->whm_server_loadavg_fifteen * 100;
			}
		}
		
		return array(
			'dataProvider' => $data,
			'time' => array_unique($time)
		);
	}
	
	public function checkAccountsLimit()
	{
		$license = new License();
		$lastLicense = $license->getLast();
		if(!$lastLicense){
			$lastLicense = new License();
		}
		$limitInfo = array(
			// Free License
			5 => 2,
			// Standard License
			1 => 10,
			3 => 10,
			// Plus License
			2 => 25,
			4 => 25,
			// Pro License
			6 => 50,
			8 => 50,
			// Unlimited License
			7 => 99999999,
			10 => 99999999
		);
		$limit = empty($limitInfo[$lastLicense->productid])? 0 : $limitInfo[$lastLicense->productid];
		
		if($this->count() < $limit){
			return true;
		}else{
			$this->addError('Account Limit', 'Maximum WHM Account limit has been reached.');
			return false;
		}
	}
	
	public function checkAccountsLimitWarning()
	{
		$license = new License();
		$lastLicense = $license->getLast();
		if(!$lastLicense){
			$lastLicense = new License();
		}
		$limitInfo = array(
			// Free License
			5 => 2,
			// Standard License
			1 => 10,
			3 => 10,
			// Plus License
			2 => 25,
			4 => 25,
			// Pro License
			6 => 50,
			8 => 50,
			// Unlimited License
			7 => 99999999,
			10 => 99999999
		);
		$limit = empty($limitInfo[$lastLicense->productid])? 0 : $limitInfo[$lastLicense->productid];
		$warningLimit = (int)($limit*0.9);
		
		return $this->count() >= $warningLimit;
	}
}